# coding=utf-8
import json

from models import TokenStore
from django.utils.crypto import get_random_string
from django.core.exceptions import ObjectDoesNotExist
from django.http import JsonResponse

import string

VALID_KEY_CHARS = string.ascii_lowercase + string.digits


class TokenService(object):
    """
    access token服务
    """
    def __init__(self):
        self.token_store = TokenStore()
        self.token_data = {}

    def save(self):
        self.token_store.token_key = self._get_or_create_token_key()
        self.token_store.token_data = json.dumps(self.token_data)
        self.token_store.token_expire = self.token_store.token_expire
        self.token_store.save()

    def get(self, token_key):
        try:
            self.token_store = TokenStore.objects.get(token_key=token_key)
            self.token_data = json.loads(self.token_store.token_data)
        except ObjectDoesNotExist:
            self.token_data = {}

    def _get_or_create_token_key(self):
        if self.token_store.token_key is '':
            self.token_store.token_key = self._get_new_token_key()

        return self.token_store.token_key

    @staticmethod
    def exists(token_key):
        if token_key is None:
            return True
        try:
            TokenStore.objects.get(token_key=token_key)
            return True
        except ObjectDoesNotExist:
            return False

    def _get_new_token_key(self):
        while True:
            token_key = get_random_string(32, VALID_KEY_CHARS)
            if not self.exists(token_key):
                return token_key


class UserLoginDecorator:
    """
    验证用户是否登陆的装饰器
    """

    def __init__(self):
        pass

    @staticmethod
    def login_require(func):
        def wrapper(*args, **kwargs):
            request = args[0]
            if len(request.token_store) > 0 and request.token_store.get('user_id', None) is not None:
                pass
            else:
                return JsonResponse({'status': 'error', 'msg': 'not_login'})
            return func(*args, **kwargs)
        return wrapper

